package com.hhd.flow.engine.cmd.impl;

import com.hhd.flow.engine.cmd.PassTaskContext;
import com.hhd.flow.engine.lisener.event.*;
import com.hhd.flow.engine.lisener.event.BeforeEnterUserTaskEvent;
import com.hhd.flow.engine.utils.FlowUtils;
import com.hhd.flow.engine.vo.ApproveType;
import com.hhd.flow.engine.vo.FlowNode;
import com.hhd.flow.engine.vo.FlowUser;
import com.hhd.flow.engine.vo.UserTask;
import com.hhd.flow.entity.FlowProcessInstance;
import com.hhd.flow.entity.FlowTask;
import com.hhd.flow.entity.FlowUserTask;
import lombok.experimental.SuperBuilder;

import java.util.List;

@SuperBuilder(toBuilder = true)
public abstract class FlowProcessEventMultiCasterCommand<T> extends FlowDoneCommand<T> {
    //开始节点的发布
    protected void publishStartProcessBeforeEvent(StartProcessCommand startProcessCommand) {
        StartProcessBeforeEvent event = FlowUtils.createStartProcessBeforeEvent(startProcessCommand);
        getEngine().onStartProcessBefore(event);
    }

    protected void publishStartProcessAfterEvent(PassTaskContext context, StartProcessCommand startProcessCommand) {
        StartProcessAfterEvent event = FlowUtils.createStartProcessAfterEvent(context, startProcessCommand);
        getEngine().onStartProcessAfter(event);
    }

    //用户节点的监听
    protected void publishBeforeEnterUserTask(UserTask userTask, PassTaskContext context, List<FlowUser> flowUsers) {
        BeforeEnterUserTaskEvent event = FlowUtils.createBeforeEnterUserTaskEvent(userTask, context, flowUsers);
        getEngine().onBeforeEnterUserTask(event);
    }

    protected void publishAfterEnterUserTask(UserTask userTask, PassTaskContext context, List<FlowUser> flowUsers, FlowTask flowTask, List<FlowUserTask> flowUserTasks) {
        AfterEnterUserTaskEvent event = FlowUtils.createAfterEnterUserTaskEvent(userTask, context, flowUsers, flowTask, flowUserTasks);
        getEngine().onAfterEnterUserTask(event);
    }

    protected void publishUserTaskCompleteBeforeEvent(FlowNode flowNode, FlowTask flowTask, PassTaskContext context) {
        UserTaskCompleteEvent event = FlowUtils.createUserTaskCompleteEvent(flowNode, flowTask, context);
        getEngine().onUserTaskBeforeComplete(event);
    }

    protected void publishUserTaskCompleteAfterEvent(FlowNode flowNode, FlowTask flowTask, PassTaskContext context) {
        UserTaskCompleteEvent event = FlowUtils.createUserTaskCompleteEvent(flowNode, flowTask, context);
        getEngine().onUserTaskAfterComplete(event);
    }

    protected void publishUserTaskCompleteBeforeEveryEvent(CompleteUserTaskCommand completeUserTaskCommand) {
        UserTaskCompleteEveryEvent event = FlowUtils.createUserTaskCompleteEveryEvent(completeUserTaskCommand);
        getEngine().onUserTaskCompleteBeforeEvery(event);
    }

    protected void publishUserTaskCompleteAfterEveryEvent(CompleteUserTaskCommand completeUserTaskCommand) {
        UserTaskCompleteEveryEvent event = FlowUtils.createUserTaskCompleteEveryEvent(completeUserTaskCommand);
        getEngine().onUserTaskCompleteAfterEvery(event);
    }

    //通过流程的监听
    protected void publishProcessBeforeApprovedEvent(PassTaskContext context) {
        ProcessApprovedEvent event = FlowUtils.createProcessApprovedEvent(context);
        getEngine().onProcessBeforeApproved(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(context.getFlowProcessInstance(), ApproveType.approve, context.getFlowModel());
        getEngine().onProcessBeforeFinish(event1);
    }

    protected void publishProcessAfterApprovedEvent(PassTaskContext context) {
        ProcessApprovedEvent event = FlowUtils.createProcessApprovedEvent(context);
        getEngine().onProcessAfterApproved(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(context.getFlowProcessInstance(), ApproveType.approve, context.getFlowModel());
        getEngine().onProcessAfterFinish(event1);
    }

    //流程不通过监听
    protected void publishFlowUserTaskBeforeEndEvent(EndCommand endCommand) {
        FlowUserTaskEndEvent event = FlowUtils.createFlowUserTaskEndEvent(endCommand);
        getEngine().onFlowUserTaskBeforeEnd(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(endCommand.getProcessInstance(), ApproveType.end, endCommand.getFlowModel());
        getEngine().onProcessBeforeFinish(event1);
    }

    protected void publishFlowUserTaskAfterEndEvent(EndCommand endCommand) {
        FlowUserTaskEndEvent event = FlowUtils.createFlowUserTaskEndEvent(endCommand);
        getEngine().onFlowUserTaskAfterEnd(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(endCommand.getProcessInstance(), ApproveType.end, endCommand.getFlowModel());
        getEngine().onProcessAfterFinish(event1);
    }

    //流程回退给发起人监听
    protected void publishFlowUserTaskBeforeToFormEvent(ToFormCommand toFormCommand) {
        FlowUserTaskToFormEvent event = FlowUtils.createFlowUserTaskToFormEvent(toFormCommand);
        getEngine().onFlowUserTaskBeforeToForm(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(toFormCommand.getProcessInstance(), ApproveType.toForm, toFormCommand.getFlowModel());
        getEngine().onProcessBeforeFinish(event1);
    }

    protected void publishFlowUserTaskAfterToFormEvent(ToFormCommand toFormCommand) {
        FlowUserTaskToFormEvent event = FlowUtils.createFlowUserTaskToFormEvent(toFormCommand);
        getEngine().onFlowUserTaskAfterToForm(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(toFormCommand.getProcessInstance(), ApproveType.toForm, toFormCommand.getFlowModel());
        getEngine().onProcessAfterFinish(event1);
    }

    protected void publishBeforeWithdraw(WithdrawCommand command) {
        WithdrawEvent event = FlowUtils.createWithdrawEvent(command);
        getEngine().onBeforeWithdraw(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(command.getFlowProcessInstance(), ApproveType.toForm, command.getFlowModel());
        getEngine().onProcessBeforeFinish(event1);
    }

    protected void publishAfterWithdraw(WithdrawCommand command) {
        WithdrawEvent event = FlowUtils.createWithdrawEvent(command);
        getEngine().onAfterWithdraw(event);

        ProcessFinishEvent event1 = FlowUtils.createProcessFinishEvent(command.getFlowProcessInstance(), ApproveType.toForm, command.getFlowModel());
        getEngine().onProcessAfterFinish(event1);
    }

    //每一个节点的进入和流出
    protected void onEnterNode(List<FlowTask> flowTasks, FlowNode flowNode, PassTaskContext context) {
        EnterNodeEvent event = FlowUtils.createEnterNodeEvent(flowTasks, flowNode, context);
        getEngine().onEnterNode(event);
    }
    public void onPassNode(FlowTask flowTask, FlowNode flowNode, PassTaskContext context) {
        PassNodeEvent event = FlowUtils.createPassNodeEvent(flowTask, flowNode, context);
        getEngine().onPassNode(event);
    }

    //创建用户任务的时候触发
    protected void publishCreateUserTaskEvent(List<FlowUserTask> flowUserTasks, FlowProcessInstance flowProcessInstance) {
        CreateUserTaskEvent event = FlowUtils.createCreateUserTaskEvent(flowUserTasks, flowProcessInstance);
        getEngine().onCreateUserTaskEvent(event);
    }
}
